package cn.virens.common.mybatis.service.dubbo.provider;

import cn.virens.common.mybatis.entity.BaseModelLock;
import cn.virens.common.mybatis.mapper.AbstrMapper;
import cn.virens.common.mybatis.mapper.example.Example;
import cn.virens.common.mybatis.service.dubbo.BaseWriteLockProvider;
import cn.virens.common.spring.retry.VirRetryException;
import cn.virens.common.util.core.Assert;
import org.springframework.transaction.annotation.Transactional;

/**
 * 通用service实现类
 *
 * @param <M> DO层接口类型
 * @param <T> 实体类型
 * @author virens
 */
public abstract class BaseWriteLockProviderImpl<M extends AbstrMapper<T>, T extends BaseModelLock> extends BaseWriteProviderImpl<M, T> implements BaseWriteLockProvider<T> {

    public BaseWriteLockProviderImpl(Class<T> clazz) {
        super(clazz);
    }

    @Override
    @Transactional(readOnly = false)
    public T updateLock(T record) throws VirRetryException {
        Assert.isNull(record.getLockFlag(), "乐观锁不可为NULL");

        Example example = Example.newInstance().and(c -> {
            c.andEqualTo("`lock_flag`", record.getLockFlag());
            c.andEqualTo("`id`", record.getId());
        });

        if (updateByExample(record.incrementAndGet(1), example) == null) {
            throw new VirRetryException("LOCK", "数据已修改或者不存在");
        } else {
            return record;
        }
    }

}
